package com.zzh.lib.core.utils;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkRequest;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.telephony.TelephonyManager;

import com.zzh.lib.core.HLibrary;
import com.zzh.lib.core.wifi.NetworkWatchCallback;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;

/**
 * Created by ZZH on 2022/3/24.
 *
 * @Date: 2022/3/24
 * @Email: zzh_hz@126.com
 * @QQ: 1299234582
 * @Author: zzh
 * @Description: 网络判断工具类
 */
public class HNetUtils {

    private HNetUtils() {
    }

    /**
     * 获取本机ipv4的地址。
     *
     * @return 例如 "127.0.0.1"
     */
    public static String getIpv4Address() {
        if (isWifiConnected()) {
            return ipv4Wifi();
        } else if (isMobileConnected()) {
            return ipv4Mobile();
        } else {
            return "127.0.0.1";
        }
    }

    private static String ipv4Mobile() {
        try {
            for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
                NetworkInterface intf = en.nextElement();
                for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
                    InetAddress inetAddress = enumIpAddr.nextElement();
                    if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {
                        return inetAddress.getHostAddress();
                    }
                }
            }
        } catch (SocketException ex) {
            LogUtils.e("获取本机IP false =" + ex);
        }

        return "127.0.0.1";
    }

    private static String ipv4Wifi() {
        WifiManager wifiManager = (WifiManager) HLibrary.getAppContext().getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        WifiInfo wifiInfo = wifiManager.getConnectionInfo();
        //调用方法将int转换为地址字符串
        //得到IPV4地址
        return intIP2StringIP(wifiInfo.getIpAddress());
    }

    static String intIP2StringIP(int ip) {
        return (ip & 0xFF) + "." +
                ((ip >> 8) & 0xFF) + "." +
                ((ip >> 16) & 0xFF) + "." +
                (ip >> 24 & 0xFF);
    }

    private static NetworkInfo getNetworkInfo() {
        ConnectivityManager mConnectivityManager = (ConnectivityManager) HLibrary.getAppContext().getSystemService(Context.CONNECTIVITY_SERVICE);
        return mConnectivityManager.getActiveNetworkInfo();
    }

    /**
     * 判断WIFI网络是否可用
     */
    public static boolean isWifiConnected() {
        ConnectivityManager mConnectivityManager = (ConnectivityManager) HLibrary.getAppContext().getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo mWiFiNetworkInfo = mConnectivityManager
                .getNetworkInfo(ConnectivityManager.TYPE_WIFI);
        if (mWiFiNetworkInfo != null) {
            return mWiFiNetworkInfo.isAvailable();
        }
        return false;
    }

    /**
     * 判断MOBILE网络是否可用
     */
    public static boolean isMobileConnected() {
        ConnectivityManager mConnectivityManager = (ConnectivityManager) HLibrary.getAppContext().getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo mMobileNetworkInfo = mConnectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
        if (mMobileNetworkInfo != null) {
            return mMobileNetworkInfo.isAvailable();
        }
        return false;
    }

    /**
     * 判断当前网络是否可用
     * 实时
     *
     * @return true 网络可用
     */
    public static boolean isNetworkConnected() {
        boolean isNetUsable = false;
        ConnectivityManager manager = (ConnectivityManager) HLibrary.getAppContext().getSystemService(Context.CONNECTIVITY_SERVICE);
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
            NetworkCapabilities networkCapabilities = manager.getNetworkCapabilities(manager.getActiveNetwork());
            if (networkCapabilities != null) {
                isNetUsable = networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
            }
        } else {
            isNetUsable = isLowVersionNetworkConnected();
        }
        return isNetUsable;
    }

    /**
     * 判断是否有网络连接
     */
    private static boolean isLowVersionNetworkConnected() {
        NetworkInfo mNetworkInfo = getNetworkInfo();
        if (mNetworkInfo != null && mNetworkInfo.isAvailable() && mNetworkInfo.isConnected()) {
            return true;
        }
        return false;
    }


    /**
     * 获取当前的网络状态  -1：没有网络  1：WIFI网络2：wap网络3：net网络
     */
    // 没有连接
    public static final int NETWORK_NONE = 0;
    // wifi连接
    public static final int NETWORK_WIFI = 1;
    // 手机网络数据连接
    public static final int NETWORK_2G = 2;
    public static final int NETWORK_3G = 3;
    public static final int NETWORK_4G = 4;
    public static final int NETWORK_5G = 5;
    public static final int NETWORK_MOBILE = 10;

    /**
     * 获取网络类型。2G,wifi,4G等
     *
     * @return
     */
    public static int getNetworkType() {

        ConnectivityManager connManager = (ConnectivityManager) HLibrary.getAppContext().getSystemService(Context.CONNECTIVITY_SERVICE);

        if (null == connManager)
            return NETWORK_NONE;

        NetworkInfo activeNetInfo = connManager.getActiveNetworkInfo();

        if (activeNetInfo == null || !activeNetInfo.isAvailable()) {

            return NETWORK_NONE;

        }
        // Wifi
        NetworkInfo wifiInfo = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);

        if (null != wifiInfo) {

            NetworkInfo.State state = wifiInfo.getState();

            if (null != state)

                if (state == NetworkInfo.State.CONNECTED || state == NetworkInfo.State.CONNECTING) {

                    return NETWORK_WIFI;

                }

        }
        // 网络
        NetworkInfo networkInfo = connManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);

        if (null != networkInfo) {

            NetworkInfo.State state = networkInfo.getState();

            String strSubTypeName = networkInfo.getSubtypeName();

            if (null != state)
                if (state == NetworkInfo.State.CONNECTED || state == NetworkInfo.State.CONNECTING) {

                    LogUtils.i("---------网络连接状态：" + activeNetInfo.getSubtype() + ", SubTypeName: " + activeNetInfo.getSubtypeName());

                    switch (activeNetInfo.getSubtype()) {

                        case TelephonyManager.NETWORK_TYPE_GPRS: // 联通2g

                        case TelephonyManager.NETWORK_TYPE_CDMA: // 电信2g

                        case TelephonyManager.NETWORK_TYPE_EDGE: // 移动2g

                        case TelephonyManager.NETWORK_TYPE_1xRTT:

                        case TelephonyManager.NETWORK_TYPE_IDEN:

                            return NETWORK_2G;

                        case TelephonyManager.NETWORK_TYPE_EVDO_A: // 电信3g

                        case TelephonyManager.NETWORK_TYPE_UMTS:

                        case TelephonyManager.NETWORK_TYPE_EVDO_0:

                        case TelephonyManager.NETWORK_TYPE_HSDPA:

                        case TelephonyManager.NETWORK_TYPE_HSUPA:

                        case TelephonyManager.NETWORK_TYPE_HSPA:

                        case TelephonyManager.NETWORK_TYPE_EVDO_B:

                        case TelephonyManager.NETWORK_TYPE_EHRPD:

                        case TelephonyManager.NETWORK_TYPE_HSPAP:
                            return NETWORK_3G;
                        case TelephonyManager.NETWORK_TYPE_LTE:
                            return NETWORK_4G;
                        case TelephonyManager.NETWORK_TYPE_NR:
                            return NETWORK_5G;
                        default://有机型返回16,17
                            //中国移动 联通 电信 三种3G制式
                            if (strSubTypeName.equalsIgnoreCase("TD-SCDMA") || strSubTypeName.equalsIgnoreCase("WCDMA") || strSubTypeName.equalsIgnoreCase("CDMA2000")) {

                                return NETWORK_3G;

                            } else {

                                return NETWORK_MOBILE;

                            }
                    }
                }
        }
        return NETWORK_NONE;
    }


    /**
     * 注册监测网络状态。
     */
    public static void registerNetworkStatus() {
        Context context = HLibrary.getAppContext();
        ConnectivityManager networkService = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            networkService.registerDefaultNetworkCallback(networkCallback);
        } else {
            networkService.registerNetworkCallback(new NetworkRequest.Builder().build(), networkCallback);
        }
    }

    /**
     * 解注册网络状态
     */
    public static void unRegisterNetworkCallback() {
        ConnectivityManager networkService = (ConnectivityManager) HLibrary.getAppContext().getSystemService(Context.CONNECTIVITY_SERVICE);
        networkService.unregisterNetworkCallback(networkCallback);

    }

    // 监听回调
    private static final ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback() {
        @Override
        public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
            super.onCapabilitiesChanged(network, networkCapabilities);
            NetworkWatchCallback networkWatchCallback = HLibrary.getInstance().getNetworkWatchCallback();
            if (networkWatchCallback != null) {
                networkWatchCallback.onCapabilitiesChanged(network, networkCapabilities);
            }
            if (isEnableToNetwork(HLibrary.getAppContext(), networkCapabilities)) {
                if (networkWatchCallback != null) {
                    networkWatchCallback.onNetworkAvailable(network);
                }
            }
        }

        //连上网络
        @Override
        public void onAvailable(Network network) {
            super.onAvailable(network);
            NetworkWatchCallback networkWatchCallback = HLibrary.getInstance().getNetworkWatchCallback();
            if (networkWatchCallback != null) {
                networkWatchCallback.onAvailable(network);
            }
        }


        @Override
        public void onLosing(Network network, int maxMsToLive) {
            NetworkWatchCallback networkWatchCallback = HLibrary.getInstance().getNetworkWatchCallback();
            if (networkWatchCallback != null) {
                networkWatchCallback.onLosing(network, maxMsToLive);
            }
        }

        /**
         * 断开网络
         * @param network
         */
        @Override
        public void onLost(Network network) {
            NetworkWatchCallback networkWatchCallback = HLibrary.getInstance().getNetworkWatchCallback();
            if (networkWatchCallback != null) {
                networkWatchCallback.onLost(network);
            }
        }

        @Override
        public void onUnavailable() {
            NetworkWatchCallback networkWatchCallback = HLibrary.getInstance().getNetworkWatchCallback();
            if (networkWatchCallback != null) {
                networkWatchCallback.onUnavailable();
            }
        }

        @Override
        public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {
            NetworkWatchCallback networkWatchCallback = HLibrary.getInstance().getNetworkWatchCallback();
            if (networkWatchCallback != null) {
                networkWatchCallback.onLinkPropertiesChanged(network, linkProperties);
            }
        }

        @Override
        public void onBlockedStatusChanged(Network network, boolean blocked) {
            NetworkWatchCallback networkWatchCallback = HLibrary.getInstance().getNetworkWatchCallback();
            if (networkWatchCallback != null) {
                networkWatchCallback.onBlockedStatusChanged(network, blocked);
            }
        }
    };

    /**
     * 检测网络连接状态是否可用，这里采用的第一种方案
     * 以下是可用网络:
     * NetworkCapabilities.TRANSPORT_CELLULAR,
     * NetworkCapabilities.TRANSPORT_WIFI,
     * NetworkCapabilities.TRANSPORT_BLUETOOTH,
     * NetworkCapabilities.TRANSPORT_ETHERNET,
     * NetworkCapabilities.TRANSPORT_VPN,
     * NetworkCapabilities.TRANSPORT_WIFI_AWARE,
     * NetworkCapabilities.TRANSPORT_LOWPAN
     */
    public static boolean isEnableToNetwork(Context context, NetworkCapabilities networkCapabilities) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
            if (context == null) return false;
            ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
            if (cm == null) return false;
            NetworkInfo mWiFiNetworkInfo = cm.getActiveNetworkInfo();
            return mWiFiNetworkInfo != null &&
                    (mWiFiNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI || mWiFiNetworkInfo.getType() == ConnectivityManager.TYPE_MOBILE);
        } else {
            return networkCapabilities != null &&
                    networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                    && networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
            /*return networkCapabilities != null &&
                    (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
                            ||networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
                            ||networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)
                            ||networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN)
                            ||networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI_AWARE)
                    );*/
        }
    }
}
